package ui

import (
	"fmt"
	"image/color"
	"lnzw/common/proto/cs_gen"
	"lnzw/engine/actor"
	"lnzw/engine/log"
	"lnzw/server/test/test_fyne/test_3/data"
	"lnzw/server/test/test_fyne/test_3/transport"
	"strconv"
	"time"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/widget"
	"go.uber.org/zap"
)

type InfoUI struct {
	IUIBase
	MapList     *widget.Select
	maplistData []string
	panel       *fyne.Container
	UnitsNum    *canvas.Text
	MonsterNum  *canvas.Text
	PlayerNum   *canvas.Text
	AddPlayer   *widget.Button
	AddMonster  *widget.Button
	CreateMap   *widget.Button
}

func NewInfoUI(parentUI IUIBase) *InfoUI {
	ui := &InfoUI{
		IUIBase:     parentUI,
		maplistData: []string{},
	}
	return ui
}

func (m *InfoUI) Init() {
	fcreatemap := EventHandle(m.OnCreateMap)
	GlobalEventMgr.Register(EventType_CreateMap, &fcreatemap)
	m.drawPanel()
}

func (m *InfoUI) OnCreateMap(event IEvent) {
	msg := event.(actor.Msg)
	creatersp, err := transport.DefaultReceive(msg)
	if err != nil {
		log.Error("unmarshal failed", zap.Error(err))
		return
	}
	rspCreateMap := creatersp.(*cs_gen.ResCreateMap)
	if rspCreateMap.Result != cs_gen.ErrorCode_SUCCESS {
		return
	}
	rsp, err := transport.DefaultSyncSendWithRsp("", data.MapMgrCatalog, &cs_gen.ReqMapList{})
	if err != nil {
		log.Error("send failed", zap.Error(err))
		return
	}
	rspMaplist := rsp.(*cs_gen.ResMapList)
	if rspMaplist.Result != cs_gen.ErrorCode_SUCCESS {
		dialog.ShowInformation("提示", "获取地图列表失败", m.GetWindow())
		return
	}
	m.maplistData = m.maplistData[:0]
	for _, mapId := range rspMaplist.MapIds {
		m.maplistData = append(m.maplistData, fmt.Sprintf("%d", mapId))
	}
	m.CreateMaplist()
	m.MapList.SetSelected(fmt.Sprintf("%d", rspCreateMap.MapId))
}

func (m *InfoUI) drawPanel() {
	// 地图列表
	m.CreateMaplist()
	// 当前单位数
	m.UnitsNum = m.drawText()
	// 当前怪物数
	m.MonsterNum = m.drawText()
	// 当前玩家数
	m.PlayerNum = m.drawText()
	// 创建地图
	m.CreateMap = m.drawButton("创建地图", fyne.NewPos(10, 540), func() {
		NewMapCreateUI(m.GetApp(), m.GetWindow())
	})
	// 添加玩家
	m.AddPlayer = m.drawButton("添加玩家", fyne.NewPos(10, 500), func() {
		// x, y := m.Map.RandPosition()
		// player := unit.NewPlayerUnit(data.GenUnitId(), x, y, viewrange)
		// m.Map.EnterMap(player)
	})
	// 添加怪物
	m.AddMonster = m.drawButton("添加怪物", fyne.NewPos(10, 540), func() {
		// x, y := m.Map.RandPosition()
		// monster := unit.NewMonsterUnit(data.GenUnitId(), x, y)
		// m.Map.EnterMap(monster)
	})
	m.panel = container.NewGridWrap(
		fyne.Size{Width: 100, Height: 40},
		m.MapList,
		m.UnitsNum,
		m.MonsterNum,
		m.PlayerNum,
		m.CreateMap,
		m.AddPlayer,
		m.AddMonster)
	m.panel.Move(fyne.NewPos(10, 30))
	m.panel.Resize(fyne.NewSize(100, 600))
	m.GetContainer().Add(m.panel)
	go func() {
		for {
			// m.UnitsNum.Text = fmt.Sprintf("当前单位数:%d", m.Map.UnitsNum())
			// m.MonsterNum.Text = fmt.Sprintf("当前怪物数:%d", m.Map.GetMonsterNum())
			// m.PlayerNum.Text = fmt.Sprintf("当前玩家数:%d", m.Map.GetPlayerNum())
			m.UnitsNum.Text = fmt.Sprintf("当前单位数:%d", 0)
			m.MonsterNum.Text = fmt.Sprintf("当前怪物数:%d", 0)
			m.PlayerNum.Text = fmt.Sprintf("当前玩家数:%d", 0)
			time.Sleep(time.Millisecond * 34)
		}
	}()
}

func (m *InfoUI) CreateMaplist() {
	m.MapList = widget.NewSelect(m.maplistData, func(s string) {
		mapId, err := strconv.ParseInt(s, 10, 64)
		if err != nil {
			log.Error("parse failed", zap.Error(err))
			return
		}
		GlobalEventMgr.Dispatch(EventType_GetMap, mapId)
	})
	if m.panel != nil {
		m.freshPanelCanvasObjects()
	}
}

func (m *InfoUI) freshPanelCanvasObjects() {
	m.panel.Objects = []fyne.CanvasObject{
		m.MapList,
		m.UnitsNum,
		m.MonsterNum,
		m.PlayerNum,
		m.CreateMap,
		m.AddPlayer,
		m.AddMonster}
	m.panel.Refresh()
}

func (m *InfoUI) drawButton(text string, pos fyne.Position, callback func()) *widget.Button {
	btn := widget.NewButton(text, callback)
	btn.Move(pos)
	btn.Resize(fyne.NewSize(100, 30))
	//m.MainContainer.Add(btn)
	return btn
}

func (m *InfoUI) drawText() *canvas.Text {
	unitsNum := canvas.NewText("", color.RGBA{R: 0, G: 0, B: 255, A: 255})
	unitsNum.TextSize = 16
	unitsNum.Alignment = fyne.TextAlignCenter
	unitsNum.TextStyle = fyne.TextStyle{
		Bold:      true,
		Italic:    true,
		Monospace: true,
		TabWidth:  20,
	}
	return unitsNum
}
